package com.small.sentinel.node;

import com.small.sentinel.slots.statistic.metric.ArrayMetric;
import com.small.sentinel.slots.statistic.metric.Metric;

import java.util.concurrent.atomic.LongAdder;

/**
 * 统计节点
 */
public class StatisticNode implements Node{

    public static volatile int SAMPLE_COUNT = 2;

    public static final int DEFAULT_WINDOW_INTERVAL_MS = 1000;

    private transient volatile Metric rollingCounterInSecond = new ArrayMetric(SAMPLE_COUNT,DEFAULT_WINDOW_INTERVAL_MS);

    private transient Metric rollingCounterInMinute = new ArrayMetric(60, 60 * 1000);

    /**
     * 当前线程数
     */
    private LongAdder curThreadNum = new LongAdder();


    @Override
    public void increaseThreadNum() {
        curThreadNum.increment();
    }

    @Override
    public void decreaseThreadNum() {
        curThreadNum.decrement();
    }

    @Override
    public int curThreadNum() {
        return (int)curThreadNum.sum();
    }

    @Override
    public void addPassRequest(int count) {
        rollingCounterInSecond.addPass(count);
        rollingCounterInMinute.addPass(count);
    }

    @Override
    public double passQps() {
        return rollingCounterInSecond.pass() / rollingCounterInSecond.getWindowIntervalInSec();
    }

    @Override
    public double previousPassQps() {
        return this.rollingCounterInMinute.previousWindowPass();
    }

    @Override
    public void addRtAndSuccess(long rt, int successCount) {
        rollingCounterInSecond.addSuccess(successCount);
        rollingCounterInSecond.addRT(rt);

        rollingCounterInMinute.addSuccess(successCount);
        rollingCounterInMinute.addRT(rt);
    }

    @Override
    public void increaseExceptionQps(int count) {
        rollingCounterInSecond.addException(count);
        rollingCounterInMinute.addException(count);
    }

    @Override
    public void increaseBlockQps(int count) {
        rollingCounterInSecond.addBlock(count);
        rollingCounterInMinute.addBlock(count);
    }
}
